#ifndef DXF_CREATIONINTERFACE_H
#define DXF_CREATIONINTERFACE_H

#include <string.h>

#include "dxf_attributes.h"
#include "dxf_codes.h"
#include "dxf_entities.h"
#include "dxf_extrusion.h"
#include "dxflib_export.h"

/**
 * Abstract class (interface) for the creation of new entities.
 * Inherit your class which takes care of the entities in the 
 * processed DXF file from this interface. 
 *
 * Double arrays passed to your implementation contain 3 double 
 * values for x, y, z coordinates unless stated differently.
 */
class DXFLIB_EXPORT DXF_CreationInterface {
public:
    DXF_CreationInterface() {
        extrusion = new DXF_Extrusion;
    }
    virtual ~DXF_CreationInterface() {
        delete extrusion;
    }

    /**
     * Called for every layer.
     */
    virtual void addLayer(const DXF_LayerAttribute& data) = 0;

    /**
     * Called for every block. Note: all entities added after this
     * command go into this block until endBlock() is called.
    *
     * @see endBlock()
     */
    virtual void addBlock(const DXF_BlockAttribute& data) = 0;

    /** Called to end the current block */
    virtual void endBlock() = 0;

    /** Called for every point */
    virtual void addPoint(const DXF_PointAttribute& data) = 0;

    /** Called for every line */
    virtual void addLine(const DXF_LineAttribute& data) = 0;

    /** Called for every arc */
    virtual void addArc(const DXF_ArcAttribute& data) = 0;

    /** Called for every circle */
    virtual void addCircle(const DXF_CircleAttribute& data) = 0;

    /** Called for every ellipse */
    virtual void addEllipse(const DXF_EllipseAttribute& data) = 0;

    /** Called for every polyline start */
    virtual void addPolyline(const DXF_PolylineAttribute& data) = 0;

    /** Called for every polyline vertex */
    virtual void addVertex(const DXF_VertexAttribute& data) = 0;
	
	/** Called for every spline */
    virtual void addSpline(const DXF_SplineAttribute& data) = 0;
	
	/** Called for every spline control point */
    virtual void addControlPoint(const DXF_ControlPointAttribute& data) = 0;
	
	/** Called for every spline knot value */
    virtual void addKnot(const DXF_KnotAttribute& data) = 0;

    /** Called for every insert. */
    virtual void addInsert(const DXF_InsertAttribute& data) = 0;
    
    /** Called for every trace start */
    virtual void addTrace(const DXF_TraceAttribute& data) = 0;
    
    /** Called for every 3dface start */
    virtual void add3dFace(const DXF_3dFaceAttribute& data) = 0;

    /** Called for every solid start */
    virtual void addSolid(const DXF_SolidAttribute& data) = 0;


    /** Called for every Multi Text entity. */
    virtual void addMText(const DXF_MTextAttribute& data) = 0;

    /**
     * Called for additional text chunks for MTEXT entities.
     * The chunks come at 250 character in size each. Note that 
     * those chunks come <b>before</b> the actual MTEXT entity.
     */
    virtual void addMTextChunk(const char* text) = 0;

    /** Called for every Text entity. */
    virtual void addText(const DXF_TextAttribute& data) = 0;

    /**
     * Called for every aligned dimension entity. 
     */
    virtual void addDimAlign(const DXF_DimensionAttribute& data,
                             const DXF_DimAlignedAttribute& edata) = 0;
    /**
     * Called for every linear or rotated dimension entity. 
     */
    virtual void addDimLinear(const DXF_DimensionAttribute& data,
                              const DXF_DimLinearAttribute& edata) = 0;

	/**
     * Called for every radial dimension entity. 
     */
    virtual void addDimRadial(const DXF_DimensionAttribute& data,
                              const DXF_DimRadialAttribute& edata) = 0;

	/**
     * Called for every diametric dimension entity. 
     */
    virtual void addDimDiametric(const DXF_DimensionAttribute& data,
                              const DXF_DimDiametricAttribute& edata) = 0;

	/**
     * Called for every angular dimension (2 lines version) entity. 
     */
    virtual void addDimAngular(const DXF_DimensionAttribute& data,
                              const DXF_DimAngularAttribute& edata) = 0;

	/**
     * Called for every angular dimension (3 points version) entity. 
     */
    virtual void addDimAngular3P(const DXF_DimensionAttribute& data,
                              const DXF_DimAngular3PAttribute& edata) = 0;
	
    /**
     * Called for every ordinate dimension entity. 
     */
    virtual void addDimOrdinate(const DXF_DimensionAttribute& data,
                             const DXF_DimOrdinateAttribute& edata) = 0;
    
    /** 
	 * Called for every leader start. 
	 */
    virtual void addLeader(const DXF_LeaderAttribute& data) = 0;
	
	/** 
	 * Called for every leader vertex 
	 */
    virtual void addLeaderVertex(const DXF_LeaderVertexAttribute& data) = 0;
	
	/** 
	 * Called for every hatch entity. 
	 */
    virtual void addHatch(const DXF_HatchAttribute& data) = 0;
	
	/** 
	 * Called for every image entity. 
	 */
    virtual void addImage(const DXF_ImageAttribute& data) = 0;

	/**
	 * Called for every image definition.
	 */
	virtual void linkImage(const DXF_ImageDefAttribute& data) = 0;

	/** 
	 * Called for every hatch loop. 
	 */
    virtual void addHatchLoop(const DXF_HatchLoopAttribute& data) = 0;

	/** 
	 * Called for every hatch edge entity. 
	 */
    virtual void addHatchEdge(const DXF_HatchEdgeAttribute& data) = 0;
	
	/** 
	 * Called after an entity has been completed.  
	 */
    virtual void endEntity() = 0;
    
    /**
     * Called for every comment in the DXF file (code 999).
     */
    virtual void addComment(const char* comment) = 0;

    /**
     * Called for every vector variable in the DXF file (e.g. "$EXTMIN").
     */
    virtual void setVariableVector(const char* key, 
	               double v1, double v2, double v3, int code) = 0;
	
    /**
     * Called for every string variable in the DXF file (e.g. "$ACADVER").
     */
    virtual void setVariableString(const char* key, const char* value, int code) = 0;
	
    /**
     * Called for every int variable in the DXF file (e.g. "$ACADMAINTVER").
     */
    virtual void setVariableInt(const char* key, int value, int code) = 0;
	
    /**
     * Called for every double variable in the DXF file (e.g. "$DIMEXO").
     */
    virtual void setVariableDouble(const char* key, double value, int code) = 0;
	
     /**
      * Called when a SEQEND occurs (when a POLYLINE or ATTRIB is done)
      */
     virtual void endSequence() = 0;

    /** Sets the current attributes for entities. */
    void setAttributes(const DXF_Attributes& attrib) {
        attributes = attrib;
    }

    /** @return the current attributes used for new entities. */
    DXF_Attributes getAttributes() {
        return attributes;
    }

    /** Sets the current attributes for entities. */
    void setExtrusion(double dx, double dy, double dz, double elevation) {
        extrusion->setDirection(dx, dy, dz);
		extrusion->setElevation(elevation);
    }

    /** @return the current attributes used for new entities. */
    DXF_Extrusion* getExtrusion() {
        return extrusion;
    }

protected:
    DXF_Attributes attributes;
    DXF_Extrusion *extrusion;
};

#endif
